home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus Leser 15 / Amiga Plus Leser CD 15.iso / Tools / Development / mmu / MuManual / C_Sources / MuProtectModules.c < prev    next >
C/C++ Source or Header  |  2002-03-12  |  16KB  |  378 lines

  1. /*****************************************************************
  2.  ** MuProtectModules                                            **
  3.  **                                                             **
  4.  ** Write-protect modules read by LoadModule for optimal safety **
  5.  ** Release 40.2, © 2001 THOR-Software inc.                     **
  6.  ** 12.05.2001 Thomas Richter                                   **
  7.  *****************************************************************/
  8.  
  9. /// Includes
  10. #include <exec/types.h>
  11. #include <exec/memory.h>
  12. #include <exec/ports.h>
  13. #include <exec/execbase.h>
  14. #include <exec/resident.h>
  15. #include <dos/dos.h>
  16. #include <mmu/mmubase.h>
  17. #include <mmu/context.h>
  18. #include <mmu/mmutags.h>
  19. #include <workbench/startup.h>
  20.  
  21. #include <thor/conversions.h>
  22.  
  23. #include <proto/exec.h>
  24. #include <proto/mmu.h>
  25. #include <proto/dos.h>
  26. #include <proto/icon.h>
  27. #include <string.h>
  28. ///
  29. /// Defines
  30. #define STRINGDATE "40.2.2001"
  31. #define STRINGVERSION "40.2"
  32. #define TEMPLATE "ON/S,OFF/S"
  33.  
  34. #define OPT_ON 0
  35. #define OPT_OFF 1
  36. #define OPT_WINDOW 2
  37. #define OPT_COUNT 3
  38. ///
  39. /// Structures
  40. /*
  41.  * The following is the main structure keeping all the resident data
  42.  * together.
  43.  *
  44.  */
  45. struct LoadResidentModule {
  46.      /* struct MemChunk         lrm_Trash;                 might be trashed by Exec on AllocAbs(): Not included here */
  47.         struct Resident         lrm_Resident;           /* our own resident structure */
  48.         UWORD                   lrm_cludgefill1;
  49.         /* the next two are for easy Kick-Tag-pointing... */
  50.         struct Resident        *lrm_ResidentPtr;
  51.         ULONG                   lrm_LastKickTag;        /* old KickTag ptr if required */
  52.         struct MemList          lrm_MemList;            /* memory for this node */
  53.         char                    lrm_Name[16];           /* name of this guy */
  54.         char                    lrm_IdString[32];       /* IDString */
  55.         ULONG                   lrm_AllocSize;          /* Includes the stack saveback */
  56.         /* pointer to the first resident module follows here */
  57.         APTR                    lrm_NULL;               /* as said, must remain blank for backwards compatibility */
  58.         APTR                    lrm_AbsLocation;        /* all of the memory at once */
  59.         ULONG                   lrm_AbsSize;            /* the size of the memory */
  60.         APTR                   *lrm_Head;
  61.         /* and now for the messy part... Embedded MC68K code */
  62.         UWORD                   lrm_LEA0;               /* load A0 with the resident structure */
  63.         UWORD                   lrm_ResidentOffset;
  64.         /* resident code follows here... */
  65. };
  66. ///
  67. /// Statics
  68. struct MMUBase *MMUBase;
  69. struct DosLibrary *DOSBase;
  70. struct ExecBase *SysBase;
  71. struct Library *IconBase;
  72. ///
  73. /// Protos
  74. int __asm __saveds main(void);
  75. struct RDArgs *ReadTTArgs(struct WBStartup *msg,LONG args[],struct RDArgs **tmp);
  76. int DisableProtection(struct LoadResidentModule *lrm);
  77. int EnableProtection(struct LoadResidentModule *lrm,BOOL aggressive);
  78. int SetModuleProtection(struct LoadResidentModule *lrm,ULONG flags,ULONG mask);
  79. ///
  80.  
  81. char version[]="$VER: MuProtectModules " STRINGVERSION " (" STRINGDATE ") © THOR";
  82.  
  83. /// main
  84. int __asm __saveds main(void)
  85. {
  86. LONG args[OPT_COUNT];
  87. struct RDArgs *rd,*myrd;
  88. struct Process *proc;
  89. int rc=20;
  90. LONG err;
  91. struct WBStartup *msg;
  92. BPTR oldout;
  93. struct MsgPort *oldconsole;
  94. struct LoadResidentModule *lrm;
  95.  
  96.  
  97.         SysBase=*((struct ExecBase **)(4L));
  98.  
  99.         memset(args,0,sizeof(LONG)*OPT_COUNT);
  100.  
  101.         /* Wait for the workbench startup, if any */
  102.         proc=(struct Process *)FindTask(NULL);
  103.  
  104.         if (!(proc->pr_CLI)) {
  105.                 WaitPort(&(proc->pr_MsgPort));
  106.                 msg=(struct WBStartup *)GetMsg(&(proc->pr_MsgPort));
  107.         } else  msg=NULL;
  108.  
  109.         if (DOSBase=(struct DosLibrary *)OpenLibrary("dos.library",37L)) {
  110.                 if (MMUBase=(struct MMUBase *)OpenLibrary("mmu.library",41L)) {
  111.  
  112.                         err = ERROR_REQUIRED_ARG_MISSING;
  113.  
  114.                         myrd=NULL;      /* reset the temporary ReadArgs */
  115.                         oldout=NULL;
  116.                         oldconsole=NULL;
  117.                         if (msg) {
  118.                                 oldout=SelectOutput(NULL);
  119.                                 oldconsole=SetConsoleTask(NULL);
  120.                                 rd=ReadTTArgs(msg,args,&myrd);
  121.                         } else  rd=ReadArgs(TEMPLATE,args,NULL);
  122.  
  123.                         if (rd) {
  124.                                 if (!GetMMUType()) {
  125.                                         Printf("MuProtectModules requires a working MMU.\n");
  126.                                         err=10;
  127.                                 } else {
  128.                                         lrm = (struct LoadResidentModule *)FindResident("« LoadModule »");
  129.  
  130.                                         if (lrm == NULL) {
  131.                                                 Printf("MuProtectModules failed: no resident modules found\n");
  132.                                                 err = 10;
  133.                                         } else {
  134.  
  135.                                                 err=0;
  136.  
  137.                                                 if (args[OPT_ON] || (!args[OPT_OFF])) {
  138.                                                         BOOL agressive = FALSE;
  139.  
  140.                                                         Forbid();
  141.                                                         if (FindTask("« MuForce »"))
  142.                                                                 agressive = TRUE;
  143.                                                         Permit();
  144.                                                         err=EnableProtection(lrm,agressive);
  145.                                                 }
  146.  
  147.                                                 if (args[OPT_OFF]) {
  148.                                                         err=DisableProtection(lrm);
  149.                                                 }
  150.                                         }
  151.                                 }
  152.  
  153.                                 FreeArgs(rd);
  154.                                 if (myrd) FreeDosObject(DOS_RDARGS,myrd);
  155.                                 if (msg)  Close(SelectOutput(NULL));
  156.                         } else  err=IoErr();
  157.  
  158.                         if (msg) {
  159.                                 SelectOutput(oldout);
  160.                                 SetConsoleTask(oldconsole);
  161.                         }
  162.  
  163.                         if (err<64) {
  164.                                 rc=err;
  165.                                 err=0;
  166.                         } else {
  167.                                 if (!msg) PrintFault(err,"MuProtectModules failed");
  168.                                 rc=10;
  169.                         }
  170.                         SetIoErr(err);
  171.  
  172.                         CloseLibrary((struct Library *)MMUBase);
  173.                 } else if (!msg) PrintFault(ERROR_OBJECT_NOT_FOUND,"MuProtectModules requires the mmu.library V41 or better");
  174.                 CloseLibrary((struct Library *)DOSBase);
  175.         }
  176.  
  177.         if (msg) {
  178.                 Forbid();
  179.                 ReplyMsg((struct Message *)msg);
  180.         }
  181.  
  182.         return rc;
  183. }
  184. ///
  185. /// ReadTTArgs
  186. struct RDArgs *ReadTTArgs(struct WBStartup *msg,LONG args[],struct RDArgs **tmp)
  187. {
  188. struct WBArg *wbarg;
  189. struct DiskObject *dop;
  190. char **tt;                      /* ToolTypes array */
  191. char *wbstr;                    /* Our self-made workbench argument string */
  192. char *here;
  193. BPTR oldlock;
  194. ULONG len;
  195. struct RDArgs *rd=NULL,*myrd=NULL;
  196. LONG err=0;
  197. BPTR newout;
  198.  
  199.         if (IconBase=OpenLibrary("icon.library",37L)) {
  200.                 if (wbarg=msg->sm_ArgList) {
  201.                         /* use a project icon if there is one... */
  202.                         if (msg->sm_NumArgs > 1) wbarg++;
  203.  
  204.                         /* go into the directory */
  205.                         oldlock=CurrentDir(wbarg->wa_Lock);
  206.  
  207.                         if (dop=GetDiskObject(wbarg->wa_Name)) {
  208.                                 if (tt=dop->do_ToolTypes) {
  209.                                         /* Read a special tool type for the output window */
  210.  
  211.                                         /* Calc the size of the argument string */
  212.  
  213.                                         len = 3;        /* reserve space for SPC,LF,NUL */
  214.                                         while (*tt) {
  215.                                                 len += strlen(*tt)+1;   /* string, plus space */
  216.                                                 tt++;
  217.                                         }
  218.  
  219.                                         if (wbstr=AllocVec(len,MEMF_PUBLIC)) {
  220.                                                 /* Now copy the arguments into this string, one by one
  221.                                                    and check whether the argument string is still valid. */
  222.  
  223.                                                 tt=dop->do_ToolTypes;
  224.                                                 here=wbstr;
  225.                                                 do{
  226.                                                         *here='\0';                     /* terminate string */
  227.                                                         /* Check whether this tool type is
  228.                                                            commented out. Just ignore it in this case */
  229.                                                         if (*tt) {
  230.                                                                 if (**tt=='(' || **tt==';')
  231.                                                                         continue;
  232.  
  233.                                                                 strcpy(here,*tt);      /* Add TT string */
  234.                                                         }
  235.                                                         len=strlen(here);
  236.                                                         here[len]='\n';
  237.                                                         here[len+1]='\0';               /* terminate string */
  238.  
  239.                                                         /* Now try to ReadArg' this string */
  240.  
  241.                                                         /* release old arguments left over from last loop */
  242.                                                         if (rd) FreeArgs(rd);
  243.                                                         if (myrd) FreeDosObject(DOS_RDARGS,myrd);
  244.                                                         rd=NULL;
  245.                                                         memset(args,0,sizeof(LONG)*OPT_COUNT);
  246.  
  247.                                                         if (myrd=AllocDosObject(DOS_RDARGS,NULL)) {
  248.                                                                 /* Allocate and setup the ReadArgs source */
  249.                                                                 myrd->RDA_Source.CS_Buffer=wbstr;
  250.                                                                 myrd->RDA_Source.CS_Length=strlen(wbstr);
  251.  
  252.                                                                 if (rd=ReadArgs(TEMPLATE ",WINDOW/K",args,myrd)) {
  253.                                                                         /* Is this still valid? */
  254.                                                                         here[len]=' ';
  255.                                                                         here+=len+1;
  256.                                                                         /* if so, accept this argument and go on */
  257.                                                                 } else {
  258.                                                                         err=IoErr();
  259.                                                                         if (err==ERROR_NO_FREE_STORE) break;
  260.                                                                         else    err=0;  /* Ignore unknown or invalid arguments silently */
  261.                                                                 }
  262.                                                         } else {
  263.                                                                 err=ERROR_NO_FREE_STORE;
  264.                                                                 break;
  265.                                                         }
  266.                                                 }while(*tt++);
  267.  
  268.                                                 FreeVec(wbstr);
  269.                                         } else err=ERROR_NO_FREE_STORE;
  270.                                 } else err=ERROR_REQUIRED_ARG_MISSING; /* Huh, how should this happen ? */
  271.                                 FreeDiskObject(dop);
  272.                         } else err=IoErr();
  273.                         CurrentDir(oldlock);
  274.                 } else err=ERROR_REQUIRED_ARG_MISSING; /* This should not happen either */
  275.                 CloseLibrary(IconBase);
  276.         } else err=ERROR_OBJECT_NOT_FOUND;    /* This should not happen */
  277.  
  278.         /* Open an output stream */
  279.  
  280.         if (err==0) {
  281.                 if (newout=Open((args[OPT_WINDOW])?((char *)args[OPT_WINDOW]):("NIL:"),MODE_NEWFILE)) {
  282.                         SelectOutput(newout);
  283.                         /* Hack in the output console. Well, well... */
  284.                         SetConsoleTask(((struct FileHandle *)(BADDR(newout)))->fh_Type);
  285.                 } else err=IoErr();
  286.         }
  287.  
  288.         if (err) {
  289.                 if (rd)   FreeArgs(rd);
  290.                 if (myrd) FreeDosObject(DOS_RDARGS,myrd);
  291.                 SetIoErr(err);
  292.                 rd=NULL;
  293.                 myrd=NULL;
  294.         }
  295.  
  296.         *tmp=myrd;
  297.         return rd;
  298. }
  299. ///
  300. /// EnableProtection
  301. int EnableProtection(struct LoadResidentModule *lrm,BOOL aggressive)
  302. {
  303.         return SetModuleProtection(lrm,(aggressive)?(MAPP_WRITEPROTECTED|MAPP_REPAIRABLE):(MAPP_ROM),MAPP_WRITEPROTECTED|MAPP_ROM|MAPP_REPAIRABLE);
  304. }
  305. ///
  306. /// DisableProtection
  307. int DisableProtection(struct LoadResidentModule *lrm)
  308. {
  309.         return SetModuleProtection(lrm,0,MAPP_WRITEPROTECTED|MAPP_ROM|MAPP_REPAIRABLE);
  310. }
  311. ///
  312. /// SetModuleProtection
  313. int SetModuleProtection(struct LoadResidentModule *lrm,ULONG flags,ULONG mask)
  314. {
  315. struct MMUContext *ctx,*sctx;   /* default context, supervisorcontext */
  316. struct MinList *ctxl,*sctxl;
  317. ULONG  pagemask;
  318. int err = 0;
  319.  
  320.         ctx=DefaultContext();   /* get the default context */
  321.         sctx=SuperContext(ctx); /* get the supervisor context for this one */
  322.  
  323.         LockContextList();
  324.         LockMMUContext(ctx);
  325.         LockMMUContext(sctx);
  326.  
  327.         /*
  328.          * first check me for page size alignment
  329.          */
  330.  
  331.         pagemask = GetPageSize(ctx) - 1;
  332.         if ((ULONG)(lrm->lrm_AbsLocation) & pagemask)
  333.                 err = 10;
  334.         if ((ULONG)(lrm->lrm_AbsSize    ) & pagemask)
  335.                 err = 10;
  336.  
  337.         if (lrm->lrm_NULL)
  338.                 err = 11;
  339.  
  340.         if (err == 0) {
  341.          err = ERROR_NO_FREE_STORE;
  342.  
  343.          if (ctxl=GetMapping(ctx)) {
  344.           if (sctxl=GetMapping(sctx)) {
  345.                 if (SetProperties(ctx, flags,mask,(ULONG)(lrm->lrm_AbsLocation),lrm->lrm_AbsSize,TAG_DONE)) {
  346.                         if (SetProperties(sctx,flags,mask,(ULONG)(lrm->lrm_AbsLocation),lrm->lrm_AbsSize,TAG_DONE)) {
  347.                                 if (RebuildTrees(ctx,sctx,NULL)) {
  348.                                         err = 0;
  349.                                 }
  350.                         }
  351.                 }
  352.  
  353.                 if (err) {
  354.                         SetPropertyList(ctx,ctxl);
  355.                         SetPropertyList(sctx,sctxl);
  356.                 }
  357.  
  358.                 ReleaseMapping(sctx,sctxl);
  359.           }
  360.           ReleaseMapping(ctx,ctxl);
  361.          }
  362.         } 
  363.  
  364.         UnlockMMUContext(sctx);
  365.         UnlockMMUContext(ctx);
  366.         UnlockContextList();
  367.  
  368.         if (err == 10) {
  369.                 Printf("MuProtectModules failed: ROM modules are not page aligned.\n");
  370.         } else if (err == 11) {
  371.                 Printf("MuProtectModules failed: incompatible version of LoadModule.\n");
  372.         }
  373.  
  374.         return err;
  375. }
  376. ///
  377.  
  378.